Skip to content

fix: Avoid UI freezes on Open Declaration with slow lang servers#1376

Merged
sebthom merged 1 commit intoeclipse-lsp4e:mainfrom
sebthom:async-open-declaration
Nov 12, 2025
Merged

fix: Avoid UI freezes on Open Declaration with slow lang servers#1376
sebthom merged 1 commit intoeclipse-lsp4e:mainfrom
sebthom:async-open-declaration

Conversation

@sebthom
Copy link
Copy Markdown
Member

@sebthom sebthom commented Nov 10, 2025

Without the PR we currently wait up to 800ms which is for some LS too short (esp. when requests pile up) so the operation may consistently fail with:

159085032-7b63dc48-ccc6-4310-812b-56bc2456a2f9

Since the wait happens in the UI thread the timeout cannot be extended without making the UI freeze longer.

With this PR the UI thread will be blocked for max 200ms (or shorter if we agree on). If the LS does not respond in that time, a DeferredOpenDeclarationHyperlink instance is returned which asynchronously opens the link once LS responded. Opening the link will be dismissed if the the editor was closed in the meantime, the document modified or the response took longer than 5 seconds.

Addresses #97

Comment thread org.eclipse.lsp4e/src/org/eclipse/lsp4e/internal/DocumentOffsetAsyncCache.java Outdated
Comment thread org.eclipse.lsp4e/src/org/eclipse/lsp4e/internal/DocumentOffsetAsyncCache.java Outdated
Comment thread org.eclipse.lsp4e/src/org/eclipse/lsp4e/internal/DocumentOffsetAsyncCache.java Outdated
Comment thread org.eclipse.lsp4e/src/org/eclipse/lsp4e/internal/DocumentOffsetAsyncCache.java Outdated
@rubenporras
Copy link
Copy Markdown
Contributor

Thanks a lot for the PR, I think with this one, LSP4E should not cause UI freezes any longer. Great work!

@sebthom sebthom force-pushed the async-open-declaration branch from 0ac9107 to d99356c Compare November 11, 2025 10:31
Block the UI thread for max 200ms. If LS does not respond return
DeferredOpenDeclarationHyperlink instance which asynchronously opens
link once LS responded.
@sebthom sebthom force-pushed the async-open-declaration branch from d99356c to 25c21e6 Compare November 11, 2025 17:37
@sebthom sebthom requested a review from rubenporras November 11, 2025 17:38
private final long ttlNanos;

public DocumentOffsetAsyncCache(final Duration ttl) {
this.ttlNanos = TimeUnit.MILLISECONDS.toNanos(ttl.toMillis());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we convert the time to nanos? Can we is millis not a good enough resolution, specially given that the input is millis?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duration calculations based on System.currentTimeMillis() is now considered bad practices as it is not time shift/leap second aware and can result in wrong calculations. Therefore one is supposted to use System.nanoTime() which returns nano seconds for measuring elapsed time.

final Supplier<CompletableFuture<V>> supplier) {
// Fast path: return a completed future if a fresh value is already cached
final @Nullable V cachedNow = getNow(doc, offset);
if (cachedNow != null)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this PR, ifs with only one statement do not have braces around the statement. I think LSP4E has the convention so far to always have braces, doesn't it? Can we have them here as well?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK we do not use braces for single return statement. At least there are plenty of cases like this.

@rubenporras rubenporras self-requested a review November 12, 2025 08:28
@rubenporras
Copy link
Copy Markdown
Contributor

@sebthom , do you plan to do more fixes soon or shall I create a new release with this and your last improvement? I think they are both very nice improvements from the user point of view.

@sebthom sebthom merged commit 04d58c9 into eclipse-lsp4e:main Nov 12, 2025
11 checks passed
@sebthom
Copy link
Copy Markdown
Member Author

sebthom commented Nov 12, 2025

@sebthom , do you plan to do more fixes soon or shall I create a new release with this and your last improvement? I think they are both very nice improvements from the user point of view.

@rubenporras I would actually appreciate a prompt release

@rubenporras
Copy link
Copy Markdown
Contributor

I will do so after I merge #1378

@sebthom sebthom deleted the async-open-declaration branch November 12, 2025 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants